<template>
  <el-dialog
    :visible="showDialog"
    :append-to-body="true"
    :close-on-click-modal="false"
    title="设备视图"
    width="850px"
    @close="dialogClose">
    <div class="device-table-content">
      <div class="flex-justify-between mar-btm-10">
        <div>
          <el-button type="primary" size="mini" @click="addGlobalDevice">
            <i class="el-icon-plus font-size-16"></i>
            <span class="mar-lft-5 font-size-14">新增设备</span>
          </el-button>
          <el-button size="mini" @click="collectChange" v-if="editorType === 'room'">
            <i class="el-icon-plus font-size-16"></i>
            <span class="mar-lft-5 font-size-14">从收藏列表添加</span>
          </el-button>
        </div>

        <el-button
          class="table-refresh-btn iconfont icon-zujiantubiao-shuaxin"
          @click="getGlobalDeviceList">
        </el-button>
      </div>
      <el-table :data="globalDeviceList" border size="mini" class="mar-btm">
        <el-table-column label="" prop="isCollect" width="50" v-if="editorType === 'room'">
          <template slot-scope="scope">
            <span :class="scope.row.isFavorite ?'el-icon-star-on  font-color-warning font-size-18':'el-icon-star-off'"
                  @click="starChange(scope.row)"></span>
          </template>
        </el-table-column>
        <el-table-column label="控制ID" prop="controlId" width="100"></el-table-column>
        <el-table-column label="设备ID" prop="_id" width="150" show-overflow-tooltip></el-table-column>
        <el-table-column label="设备名称" show-overflow-tooltip>
          <template slot-scope="scope">
            {{scope.row.deviceOtherName ? scope.row.deviceOtherName : scope.row.deviceName}}
          </template>
        </el-table-column>
        <el-table-column label="协议名称" prop="protocolName" show-overflow-tooltip></el-table-column>
        <el-table-column label="操作" width="160">
          <template slot-scope="scope">
            <el-button size="mini" @click="editGlobalDevice(scope.row)">编辑</el-button>
            <el-button size="mini" type="danger" @click="deleteGlobalDevice(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!--编辑房间设备-->
    <el-dialog
      :title="`${!isEditDevice ? '新增' : '编辑'}房间设备`"
      :visible.sync="showDeviceDialog"
      width="850px"
      :close-on-click-modal="false"
      append-to-body>
      <el-form
        v-loading="deviceFormLoading"
        :ref="deviceFormRef"
        :model="deviceForm"
        :rules="deviceFormRules"
        size="small" label-width="80px">
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="设备类型" prop="deviceTypeId">
              <el-select
                v-model="deviceForm.deviceTypeId"
                clearable filterable
                class="width-100"
                placeholder="请选择设备类型"
                @change="deviceTypeChange">
                <el-option
                  v-for="(deviceType, idx) in deviceTypeList" :key="idx"
                  :label="deviceType.name" :value="deviceType._id"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备厂家" prop="manufacturerId">
              <el-select
                v-model="deviceForm.manufacturerId"
                clearable filterable
                class="width-100"
                placeholder="请选择设备厂家"
                @change="manufacturerChange">
                <el-option
                  v-for="(manufacturer, idx) in manufacturerList" :key="idx"
                  :label="manufacturer.label" :value="manufacturer.value"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备系列" prop="seriesId">
              <el-select
                v-model="deviceForm.seriesId"
                clearable filterable
                class="width-100"
                placeholder="请选择设备系列"
                @change="seriesChange">
                <el-option
                  v-for="(series, idx) in seriesList" :key="idx"
                  :label="series.label" :value="series.value"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备型号" prop="deviceId">
              <el-select
                v-model="deviceForm.deviceId"
                clearable filterable
                class="width-100"
                placeholder="请选择设备型号"
                @change="deviceChange">
                <el-option
                  v-for="(device, idx) in deviceList" :key="idx"
                  :label="device.deviceName" :value="device._id"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备协议" prop="protocolId">
              <el-select
                v-model="deviceForm.protocolId"
                clearable filterable
                class="width-100"
                placeholder="请选择设备协议">
                <el-option
                  v-for="(protocol, idx) in protocolList" :key="idx"
                  :label="protocol.label" :value="protocol.value"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备别名">
              <el-input v-model="deviceForm.deviceOtherName" placeholder="请填写设备别名" size="small"
                        class="width-90 mar-rgt-10"></el-input>
              <el-tooltip class="item" effect="dark" content="对当前设备名称进行自定义命名" placement="left-start">
                <i class="el-icon-question"></i>
              </el-tooltip>
            </el-form-item>
          </el-col>
          <el-col v-if="isEditDevice" :span="12">
            <el-form-item label="控制ID" prop="controlId">
              <el-input v-model="deviceForm.controlId" placeholder="请填写控制ID" size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="自定义命令" prop="customCommand">
          <el-button type="primary" size="mini" @click="addCustomCommand" class="mar-btm-10">添加命令</el-button>
          <el-table :data="deviceForm.customCommand" border size="mini" class="mar-btm">
            <el-table-column prop="name" label="命令类型" width="120">
              <template slot-scope="scope">
                <el-select v-model="scope.row.type" class="width-100" placeholder="请选择命令类型" size="mini">
                  <el-option label="HEX" value="hex"></el-option>
                  <el-option label="ASCII" value="ascii"></el-option>
                </el-select>
              </template>
            </el-table-column>
            <el-table-column prop="name" label="命令名称" width="180">
              <template slot-scope="scope">
                <el-input v-model="scope.row.commandName" placeholder="请输入命令名称" size="mini"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="type" label="码流内容">
              <template slot-scope="scope">
                <el-input v-model="scope.row.codeStream" placeholder="请输入码流内容" size="mini"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="160">
              <template slot-scope="scope">
                <el-button size="mini" @click="copyCustomCommand(scope.$index, scope.row)">复制</el-button>
                <el-button size="mini" type="danger" @click="deleteCustomCommand(scope.$index, scope.row)">删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <div class="mar-top text-align-right">
        <el-button type="info" @click="showDeviceDialog = false">取消</el-button>
        <el-button type="primary" @click="deviceFormSubmit">提交</el-button>
      </div>
    </el-dialog>
    <!--新增房间设备-->
    <el-dialog
      title="新增房间设备"
      :visible.sync="showAddDeviceDialog"
      v-loading="addDeviceFormLoading"
      width="850px"
      :close-on-click-modal="false"
      append-to-body>
      <ChoseDevice ref="choseDevice" @selectDevice="selectDeviceHandle"></ChoseDevice>
      <div class="mar-top text-align-right">
        <el-button type="info" @click="showAddDeviceDialog = false">取消</el-button>
        <el-button type="primary" @click="AddDeviceFormSubmit">提交</el-button>
      </div>
    </el-dialog>

    <!--收藏列表-->
    <el-dialog
      title="收藏列表"
      :visible.sync="showCollectDeviceDialog"
      width="850px"
      :close-on-click-modal="false"
      append-to-body>
      <el-table :data="collectDeviceList" border size="mini" class="mar-btm"
                @selection-change="handleSelectionCollectDevice">
        <el-table-column
          type="selection"
          width="55">
        </el-table-column>
        <el-table-column label="设备ID" prop="_id" width="150" show-overflow-tooltip></el-table-column>
        <el-table-column label="设备名称" show-overflow-tooltip>
          <template slot-scope="scope">
            {{scope.row.deviceOtherName ? scope.row.deviceOtherName : scope.row.deviceName}}
          </template>
        </el-table-column>
        <el-table-column label="协议名称" prop="protocolName" show-overflow-tooltip></el-table-column>
        <el-table-column label="操作" width="160">
          <template slot-scope="scope">
            <el-button size="mini" type="danger" @click="deleteCollectDevice(scope.row)">移除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="mar-top text-align-center">
        <el-button type="info" size="small" @click="showCollectDeviceDialog = false">取消</el-button>
        <el-button type="primary" size="small" @click="addToGlobalDeviceSubmit">添加</el-button>
      </div>
    </el-dialog>
  </el-dialog>
</template>

<script>
  import {confirmHandle, deepCopyWithJson, downloadFileApi, generateUID, messageHandle,hasAnyEmptyProperty} from "@/utils";
  import EZTable from "@/components/table/EZTable.vue";
  import {msgCode} from "@/config/string";
  import {mapActions, mapState} from "vuex";
  import API from "@/api";
  import _ from "lodash";
  import ChoseDevice from "@/page/IDE/editor/global/ChoseDevice.vue";

  export default {
    name: "GlobalDevices",
    components: {EZTable, ChoseDevice},
    model: {
      prop: 'showDialog',
      event: 'change'
    },
    props: {
      editorType: {
        type: String,
        default: 'room', // room/component
      },
      showDialog: {
        type: Boolean,
        default: false,
      },
      devices: {
        type: Array,
        default: () => {
          return [];
        }
      },
      roomId: {
        type: String,
        default: '',
      },
      componentId: {
        type: String,
        default: '',
      },
    },
    data() {
      return {
        tableLoading: true,
        tableHdl: null,
        deviceTypeList: [],
        manufacturerList: [],
        seriesList: [],
        deviceList: [],
        protocolList: [],
        showDeviceDialog: false,
        isEditDevice: false,
        deviceFormLoading: false,
        addDeviceFormLoading: false,
        deviceFormRef: 'deviceFormRef',
        deviceForm: {
          deviceTypeId: '',
          manufacturerId: '',
          seriesId: '',
          modelId: '',
          deviceId: '',
          deviceCode: '',
          protocolId: '',
          protocols: [],
          controlId: '',
          customCommand: [],
          deviceOtherName: ''
        },
        deviceFormRules: {
          deviceTypeId: [{required: true, message: '请选择设备类型', trigger: 'change'}],
          manufacturerId: [{required: true, message: '请选择设备厂家', trigger: 'change'}],
          seriesId: [{required: true, message: '请选择设备系列', trigger: 'change'}],
          deviceId: [{required: true, message: '请选择设备型号', trigger: 'change'}],
          controlId: [{required: true, message: '请输入控制ID', trigger: 'blur'}],
          protocolId: [{required: true, message: '请选择设备协议', trigger: 'change'}],
        },
        multipleSelection: [],
        showCollectDeviceDialog: false,
        showAddDeviceDialog: false,
        collectDeviceList: [],
        selectDeviceList: [],

      };
    },
    computed: {
      ...mapState({
        globalDeviceList: state => state.ide.globalDeviceList,
      }),
    },
    mounted() {
      this.initDeviceForm();
      this.getGlobalDeviceList();
      this.getDeviceTypeList();
      this.$EventBus.$on('refreshGlobalDevices', this.getGlobalDeviceList);
    },
    beforeDestroy() {
      this.$EventBus.$off('refreshGlobalDevices');
    },
    methods: {
      ...mapActions(['updateGlobalDeviceList']),
      // 获取设备列表
      getGlobalDeviceList() {
        this.tableLoading = true;
        switch (this.editorType) {
          case 'room':
            API.roomDevice.roomDeviceList({roomId: this.roomId}).then((resp) => {
              this.tableLoading = false;
              const {data = []} = resp;
              this.updateGlobalDeviceList(data);
            }).catch((err) => {
              console.log("err: ", err);
              this.tableLoading = false;
            });
            break;
          case 'component':
            API.componentDevice.componentDeviceList({componentId: this.componentId}).then((resp) => {
              this.tableLoading = false;
              const {data = []} = resp;
              this.updateGlobalDeviceList(data);
            }).catch((err) => {
              console.log("err: ", err);
              this.tableLoading = false;
            });
            break;
          default:
            break;
        }
      },
      addGlobalDevice() {
        this.isEditDevice && this.resetDeviceForm();
        this.showAddDeviceDialog = true;
        this.isEditDevice = false;

      },

      handleSelectionCollectDevice(val) {
        this.multipleSelection = val;
      },
      editGlobalDevice(device) {
        this.deviceForm = _.cloneDeep(device);
        this.getManufacturerList();
        this.getSeriesList();
        this.getDeviceList();
        this.getProtocolList([this.deviceForm.protocolId]);
        this.isEditDevice = true;
        this.showDeviceDialog = true;
      },
      deleteGlobalDevice(device) {
        const {_id, deviceName = ''} = device;
        const message = `确定要删除设备：${deviceName} 吗?设备删除后，组件关联的设备将会被清空，请谨慎操作！`
        confirmHandle({label: message}).then(() => {
          switch (this.editorType) {
            case 'room':
              API.roomDevice.roomDeviceDelete({_id}).then(resp => {
                messageHandle({code: msgCode.DELETE_SUCCESS, title: "设备"});
                this.getGlobalDeviceList();
              });
              break;
            case 'component':
              API.componentDevice.componentDeviceDelete({_id}).then(resp => {
                messageHandle({code: msgCode.DELETE_SUCCESS, title: "设备"});
                this.getGlobalDeviceList();
              });
              break;
            default:
              break;
          }
        }).catch(() => {
        });
      },
      initDeviceForm() {
        this.deviceForm = {
          deviceTypeId: '',
          manufacturerId: '',
          seriesId: '',
          modelId: '',
          deviceId: '',
          deviceCode: '',
          protocolId: '',
          controlId: '',
          customCommand: [],
          deviceOtherName: ''
        }
      },
      resetDeviceForm() {
        this.initDeviceForm();
        const deviceForm = this.$refs[this.deviceFormRef];
        deviceForm && deviceForm.resetFields();
      },
      getDeviceTypeList() {
        API.deviceType.deviceTypeAll().then(resp => {
          const {data = []} = resp;
          this.deviceTypeList = data;
        }).catch(err => {
          console.log('err', err);
        });
      },
      deviceTypeChange() {
        this.deviceForm.seriesId = '';
        this.deviceForm.modelId = '';
        this.deviceForm.deviceId = '';
        this.deviceForm.deviceCode = '';
        this.deviceForm.protocolId = '';
        this.seriesList = [];
        this.deviceList = [];
        this.protocolList = [];
        this.getManufacturerList();
      },
      getManufacturerList() {
        const param = {
          deviceType: this.deviceForm.deviceTypeId
        };
        API.manufacturer.manufacturerByDeviceType(param).then(resp => {
          const {data = []} = resp;
          this.manufacturerList = data;
        }).catch(err => {
          console.log('err', err);
        });
      },
      manufacturerChange() {
        this.deviceForm.seriesId = '';
        this.deviceForm.modelId = '';
        this.deviceForm.deviceId = '';
        this.deviceForm.deviceCode = '';
        this.deviceForm.protocolId = '';
        this.seriesList = [];
        this.deviceList = [];
        this.protocolList = [];
        this.getSeriesList();
      },
      getSeriesList() {
        const param = {
          deviceType: this.deviceForm.deviceTypeId,
          manufacturer: this.deviceForm.manufacturerId
        };
        API.series.seriesByManufacturer(param).then(resp => {
          const {data = []} = resp;
          this.seriesList = data;
        }).catch(err => {
          console.log('err', err);
        });
      },
      seriesChange() {
        this.deviceForm.modelId = '';
        this.deviceForm.deviceId = '';
        this.deviceForm.deviceCode = '';
        this.deviceForm.protocolId = '';
        this.deviceList = [];
        this.protocolList = [];
        this.getDeviceList();
      },
      getDeviceList() {
        const param = {
          deviceType: this.deviceForm.deviceTypeId,
          manufacturer: this.deviceForm.manufacturerId,
          series: this.deviceForm.seriesId
        };
        API.device.deviceAll(param).then(resp => {
          const {data = []} = resp;
          this.deviceList = data;
        }).catch(err => {
          console.log('err', err);
        });
      },
      deviceChange(deviceId) {
        const device = this.deviceList.find(d => d._id === deviceId);
        const {model = '', deviceCode = '', protocols = []} = device;
        this.deviceForm.modelId = model;
        this.deviceForm.deviceCode = deviceCode;
        this.deviceForm.protocolId = '';
        this.deviceForm.protocols = _.map(protocols, 'protocol');
        this.protocolList = [];
        this.getProtocolList(this.deviceForm.protocols);
      },
      getProtocolList(protocols) {
        const param = {_id: {$in: protocols}};
        API.protocol.protocolAll(param).then(resp => {
          const {data = []} = resp;
          this.protocolList = data;
        }).catch(err => {
          console.log('err', err);
        });
      },
      deviceFormSubmit() {
        this.$refs[this.deviceFormRef].validate((valid) => {
          if (!valid) return;
          if(this.deviceForm.customCommand.length>0){
            if(hasAnyEmptyProperty(this.deviceForm.customCommand,'codeStream')||hasAnyEmptyProperty(this.deviceForm.customCommand,'commandName')){
              this.$notify({
                message: '请填写完整的自定义码流',
                type: 'error',
                duration: 3000,
              });
              return
            }
          }
          let api;
          let title = '';
          const code = !this.isEditDevice ? msgCode.ADD_SUCCESS : msgCode.EDIT_SUCCESS;
          const param = this.deviceForm;
          switch (this.editorType) {
            case 'room':
              title = '房间设备';
              param.roomId = this.roomId;
              api = !this.isEditDevice ? API.roomDevice.roomDeviceAdd : API.roomDevice.roomDeviceEdit;
              break;
            case 'component':
              title = '组件设备';
              param.componentId = this.componentId;
              api = !this.isEditDevice ? API.componentDevice.componentDeviceAdd : API.componentDevice.componentDeviceEdit;
              break;
            default:
              break;
          }
          this.deviceFormLoading = true;
          api(param).then(resp => {
            this.showDeviceDialog = false;
            messageHandle({code: code, title: title});
            this.deviceFormLoading = false;
            this.getGlobalDeviceList();
            this.resetDeviceForm();
          }).catch(err => {
            console.log('err', err);
            this.deviceFormLoading = false;
          });
        });
      },
      AddDeviceFormSubmit() {
        if (this.selectDeviceList.length === 0) {
          this.$notify({
            message: '请选择设备协议',
            type: 'error',
            duration: 3000,
          });
          return
        }
        const params = this.selectDeviceList.map(item => {
          return {
            ...(this.editorType === 'room' && {roomId: this.roomId}),
            ...(this.editorType === 'component' && {componentId: this.componentId}),
            controlId: "",
            customCommand: [],
            deviceCode: item.deviceCode,
            deviceId: item._id,
            deviceTypeId: item.deviceType,
            manufacturerId: item.manufacturer,
            modelId: item.model,
            protocolId: item.protocolId,
            protocols: item.protocols,
            seriesId: item.series,
          }
        })
        let api;
        let title = '';
        switch (this.editorType) {
          case 'room':
            title = '房间设备';
            api = API.roomDevice.roomDeviceAdd
            break;
          case 'component':
            title = '组件设备';
            api = API.componentDevice.componentDeviceAdd
            break;
          default:
            break;
        }
        this.addDeviceFormLoading = true;
        console.log('params', params);
        api(params).then(resp => {
          this.showAddDeviceDialog = false;
          this.addDeviceFormLoading = false;
          this.getGlobalDeviceList();
          this.$refs.choseDevice.initForm()
          messageHandle({code: msgCode.ADD_SUCCESS, title: title});
          this.selectDeviceList=[]
        }).catch(err => {
          console.log('err', err);
          this.addDeviceFormLoading = false;
        });

      },
      addCustomCommand() {
        const {customCommand = []} = this.deviceForm;
        const commandName = `自定义命令${customCommand.length + 1}`;
        customCommand.push({
          id: generateUID(),
          commandName: commandName,
          type: 'hex',
          codeStream: ''
        });
      },
      copyCustomCommand(idx) {
        const src = deepCopyWithJson(this.deviceForm.customCommand[idx]);
        src.id = generateUID()
        this.deviceForm.customCommand.splice(idx, 0, src);
      },
      deleteCustomCommand(idx, command = {}) {
        this.deviceForm.customCommand.splice(idx, 1);
      },
      dialogClose() {
        this.$emit('change', false);
      },
      addToGlobalDeviceSubmit() {
        this.$confirm(`是否从收藏夹中添加${this.multipleSelection.length}个设备到设备视图`, '添加设备', {
          distinguishCancelAndClose: true,
          confirmButtonText: '是',
          cancelButtonText: '否'
        }).then(() => {
          this.multipleSelection.forEach(item => {
            item.roomId = this.roomId;
            delete item._id;
          })
          API.roomDevice.roomDeviceAdd(this.multipleSelection).then(resp => {
            messageHandle({type: 'success', msg: '添加设备成功！'});
            this.getGlobalDeviceList();
            this.showCollectDeviceDialog = false;
          }).catch(err => {
            console.log('err', err);
          });
        }).catch(action => {
        });
      },
      deleteCollectDevice(row) {
        this.$confirm('是否从收藏夹中移除当前设备', '移除收藏', {
          distinguishCancelAndClose: true,
          confirmButtonText: '是',
          cancelButtonText: '否'
        }).then(() => {
          this.delStarChange('CollectList', row._id);
        }).catch(action => {
        });
      },
      delStarChange(type, id) {
        API.roomDevice.roomDeviceFavoritesDel({_id: id}).then(result => {
          this.$message({
            message: '取消收藏成功',
            type: 'success'
          });
          if (type === 'CollectList') {
            this.getCollectListData()
          }
        }).catch(err => {
          console.log('err', err)
        });
      },
      getCollectListData() {
        API.roomDevice.roomDeviceFavoritesList().then(result => {
          this.collectDeviceList = result.data;
        }).catch(err => {
          console.log('err', err)
        });
      },
      starChange(row) {
        if (!row.isFavorite) {
          API.roomDevice.roomDeviceFavoritesAdd({itemType: 'roomDevice', itemId: row._id}).then(result => {
            this.$message({
              message: '添加收藏成功',
              type: 'success'
            });
            this.getGlobalDeviceList();
          }).catch(err => {
            console.log('err', err)
          });
        } else {
          this.delStarChange('deviceList', row._id);
          this.getGlobalDeviceList();
        }
      },
      collectChange() {
        this.showCollectDeviceDialog = true;
        this.getCollectListData();
      },
      selectDeviceHandle(row) {
        this.selectDeviceList = row
      }
    },
  };
</script>

<style lang="less" scoped>

  .device-table-content {
    .table-refresh-btn {
      text-align: center;
      font-size: @sizeRegular;
      padding: @paddingSecond !important;
      border: none !important;
      margin-left: @paddingSecond !important;
    }

    .table-refresh-btn:hover {
      background: @colorBlackAlpha05 !important;
      color: @colorPrimary !important;
    }
  }

  .divider {
    height: 2px;
    background: #eee;
    margin: 10px 0;
  }
</style>
